home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / database / hl / hl-1.002 / hl-1 / Librarian / Librarian.cc next >
Encoding:
C/C++ Source or Header  |  1995-04-14  |  10.8 KB  |  416 lines

  1. /* -*- Mode: C -*- */
  2. /* Librarian.cc - Librarian - query program main line
  3.  * Created by Robert Heller on Tue Mar 17 16:57:42 1992
  4.  *
  5.  * ------------------------------------------------------------------
  6.  * Home Libarian by Deepwoods Software
  7.  * Librarian program - search a card catalog
  8.  * ------------------------------------------------------------------
  9.  * Modification History:
  10.  * ------------------------------------------------------------------
  11.  * Contents:
  12.  * ------------------------------------------------------------------
  13.  * 
  14.  * 
  15.  * Copyright (c) 1991,1992 by Robert heller (D/B/A Deepwoods Software)
  16.  *        All Rights Reserved
  17.  * 
  18.  */
  19.  
  20. #include <stream.h>
  21. #include <vBTree.h>
  22. #include <ctype.h>
  23. #ifdef MESSYDOS
  24. #include <CardRec.h>
  25. #include <ListRec.h>
  26. #else
  27. #include <CardRecord.h>
  28. #include <ListRecord.h>
  29. #endif
  30. #include <Terminal.h>
  31. #ifdef MESSYDOS
  32. #include <CmdScren.h>
  33. #include <ScrPmt.h>
  34. #include <LLScrPmt.h>
  35. #else
  36. #include <CommandScreen.h>
  37. #include <ScrollPrompt.h>
  38. #include <LLScrollPrompt.h>
  39. #endif
  40. #define VERSION "V1.0Beta"
  41. #ifdef MESSYDOS
  42. #include "Libraria.h"
  43. #else
  44. #include "Librarian.h"
  45. #endif
  46.  
  47. #ifdef unix
  48. #include <stdio.h>
  49. #endif
  50.  
  51. static vBTree *Tree;
  52. static Terminal *Term;
  53.  
  54. const DisplayBufferSize = 4096;
  55. const Margin = 256;
  56. static char DisplayBuffer[DisplayBufferSize];
  57.  
  58. void DispCard(Key inkey)
  59. {
  60.     int column;
  61.     int lines = 0;
  62.     ScrollPrompt CardOutput("",3,0,80,15,20);
  63.     static char answer[1];
  64.     CoreItem item;
  65.     if (!(Tree->SearchId(inkey,&item) &&
  66.           strlen(inkey) == strlen(item.key))) return;        
  67.     char* outptr = DisplayBuffer;
  68.     strcpy(outptr,item.key); outptr += strlen(item.key);
  69.     *outptr++ = '\n';
  70.     *outptr++ = '\n';
  71.     if (item.data.size > 0) {
  72.         CardRecord rec(&item.data);
  73.         register Card *c = &rec;
  74.         char* tn = TypeName(c->type);
  75.         strcpy(outptr,c->author); outptr += strlen(c->author);
  76.         *outptr++ = ',';
  77.         *outptr++ = ' ';
  78.         sprintf(outptr,"%d\n",c->year); outptr += strlen(outptr);
  79.         strcpy(outptr,"    "); outptr += strlen(outptr);
  80.         strcpy(outptr,c->title); outptr += strlen(outptr);
  81.         *outptr++ = '\n';
  82.         strcpy(outptr,"    "); outptr += strlen(outptr);
  83.         strcpy(outptr,tn); outptr += strlen(tn);
  84.         *outptr++ = '\n';
  85.         strcpy(outptr,"    Published by "); outptr += strlen(outptr);
  86.         strcpy(outptr,c->publisher); outptr += strlen(outptr);
  87.         *outptr++ = ' ';
  88.         strcpy(outptr,c->city); outptr += strlen(outptr);
  89.         *outptr++ = '\n';
  90.         if (c->vol != 0) {
  91.             sprintf(outptr,"    Volume: %d",c->vol);
  92.             outptr += strlen(outptr);
  93.         }
  94.         *outptr++ = '\n';
  95.         *outptr++ = '\n';
  96.         column = 0;
  97.         for (char* p = c->description; lines < 22 && *p != 0; p++) {
  98.             if (*p != '\n' && column < 4) {
  99.                 *outptr++ = ' ';
  100.                 *outptr++ = ' ';
  101.                 *outptr++ = ' ';
  102.                 *outptr++ = ' ';
  103.                 column = 4;
  104.             }
  105.             if (*p == '\n') {
  106.                 *outptr++ = '\n';
  107.                 lines++;
  108.                 column = 0;
  109.             } else if (column > 78) {
  110.                 *outptr++ = '\\';
  111.                 *outptr++ = '\n';
  112.                 lines++;
  113.                 column = 0;
  114.                 p--;
  115.             } else if (*p == '\t') {
  116.                 do {
  117.                     *outptr++ = ' ';
  118.                     column++;
  119.                 } while ((column % 8) != 0);
  120.             } else {
  121.                 *outptr++ = *p;
  122.                 column++;
  123.             }
  124.         }
  125.         if (column > 0) {
  126.             *outptr++ = '\n';
  127.             lines++;
  128.         }
  129.         *outptr = '\0';
  130.         CardOutput.Scroll(DisplayBuffer,"Hit RETURN to continue",answer,1);
  131.     }
  132. }
  133.  
  134. int ListCards()
  135. {
  136.     CoreItem item;
  137.     Key searchkey;
  138.     static char title[80], line[LineLength];
  139.     Term->PromptLine(18,0,"Search prefix: ",searchkey,KeySize);
  140.     sprintf(title,"Ids matching %s",searchkey);
  141.     LLScrollPrompt IdList(title,3,0,80,15,20);
  142.     LineList* llist = (LineList*) 0;
  143.     LineList** ptr = &llist;
  144.     LineList* prev = (LineList*) 0;
  145.     if (Tree->SearchId(searchkey,&item)) {
  146.         do {
  147.             int fill;
  148.             char* p = line;
  149.             strcpy(p,item.key);
  150.             fill = KeySize - strlen(item.key);
  151.             p += strlen(item.key);
  152.             while (fill-- > 0) *p++ = ' ';
  153.             *p++ = ' ';
  154.             {
  155.                 CardRecord crec(&item.data);
  156.                 strcpy(p,crec->title);
  157.                 p += strlen(crec->title);
  158.             }
  159.             *p++ = 0;
  160.             LineList* newline = new LineList(line,0,prev);
  161.             *ptr = newline;
  162.             prev = newline;
  163.             ptr = &newline->nextline;
  164.             //cerr << "*** line = '" << line << "'\n";
  165.         } while (Tree->SearchIdAgain(&item));
  166.         if (llist != (LineList*) 0) {
  167.             if (IdList.Scroll(llist,"Card to view (RETURN for more, q to exit):",title,KeySize) > 0) 
  168.                 DispCard(title);
  169.             FreeLineList(llist);
  170.         }
  171.         return(-1);
  172.     } else {
  173.         Term->Message("No ids found");
  174.         return(1);
  175.     }
  176. }
  177.  
  178. int ListCardsFromList(char* title,ListRecord& list)
  179. {
  180.     CoreItem item;
  181.     static Key newkey;
  182.     static char line[LineLength];
  183.     LLScrollPrompt IdList(title,3,0,80,15,20);
  184.     LineList* llist = (LineList*) 0;
  185.     LineList** ptr = &llist;
  186.     LineList* prev = (LineList*) 0;
  187.     int numids = list.ElementCount();
  188.     for (int i = 0; i < numids; i++) {
  189.         if (Tree->SearchId(list[i],&item) && strlen(list[i]) == strlen(item.key)) {
  190.             int fill;
  191.             char* p = line;
  192.             strcpy(p,item.key);
  193.             fill = KeySize - strlen(item.key);
  194.             p += strlen(item.key);
  195.             while (fill-- > 0) *p++ = ' ';
  196.             *p++ = ' ';
  197.             {
  198.                 CardRecord crec(&item.data);
  199.                 strcpy(p,crec->title);
  200.                 p += strlen(crec->title);
  201.             }
  202.             *p++ = 0;
  203.             LineList* newline = new LineList(line,0,prev);
  204.             *ptr = newline;
  205.             prev = newline;
  206.             ptr = &newline->nextline;
  207.         }
  208.     }
  209.     if (llist != (LineList*) 0) {
  210.         if (IdList.Scroll(llist,"Card to view (RETURN for more, q to exit):",title,KeySize) > 0) 
  211.             DispCard(title);
  212.         FreeLineList(llist);
  213.     }
  214.     return(-1);
  215. }
  216.  
  217. int ListTitles()
  218. {
  219.     CoreItem item;
  220.     Key searchkey;
  221.     static char title[80],header[80],line[LineLength];
  222.     Term->PromptLine(18,0,"Search prefix: ",searchkey,KeySize);
  223.     sprintf(title,"Titles matching %s",searchkey);
  224.     LLScrollPrompt TitleList(title,3,0,80,15,20);
  225.     LineList* llist = (LineList*) 0;
  226.     LineList** ptr = &llist;
  227.     LineList* prev = (LineList*) 0;
  228.     int i;
  229.     int refnum = 0;
  230.     if (Tree->SearchTitle(searchkey,&item)) {
  231.         do {
  232.             refnum++;
  233.             sprintf(line,"%3d: %s",refnum,item.key);
  234.             LineList* newline = new LineList(line,0,prev);
  235.             *ptr = newline;
  236.             prev = newline;
  237.             ptr = &newline->nextline;
  238.         } while (Tree->SearchTitleAgain(&item));
  239.         if (llist != (LineList*) 0) {
  240.             if (refnum == 1) {
  241.                 if (Tree->SearchTitle(llist->thisline+5,&item)) {
  242.                     sprintf(header,"Ids for title %s",item.key);
  243.                     ListRecord rec(&item.data);
  244.                     if (rec.ElementCount() == 1) DispCard(rec[0]);
  245.                     else if (rec.ElementCount() > 1)
  246.                         ListCardsFromList(header,rec);
  247.                 }
  248.             } else if (TitleList.Scroll(llist,"Ref#, RETURN for more, q to exit:",title,KeySize) > 0) {
  249.                 refnum = atoi(title);
  250.                 for (i = 1,prev = llist;
  251.                      prev != (LineList*)0 && i < refnum;
  252.                      prev = prev->nextline,i++) ;
  253.                 if (i == refnum) {
  254.                     if (Tree->SearchTitle(prev->thisline+5,&item)) {
  255.                         sprintf(header,"Ids for title %s",item.key);
  256.                         ListRecord rec(&item.data);
  257.                         if (rec.ElementCount() == 1) DispCard(rec[0]);
  258.                         else if (rec.ElementCount() > 1)
  259.                             ListCardsFromList(header,rec);
  260.                     }
  261.                 } else Term->Message("Bad reference number");
  262.             }
  263.             FreeLineList(llist);
  264.         }
  265.         return(-1);
  266.     } else {
  267.         Term->Message("No titles found");
  268.         return(1);
  269.     }
  270. }
  271.  
  272. int ListAuthors()
  273. {
  274.     CoreItem item;
  275.     Key searchkey;
  276.     static char title[80],header[80],line[LineLength];
  277.     Term->PromptLine(18,0,"Search prefix: ",searchkey,KeySize);
  278.     sprintf(title,"Authors matching %s",searchkey);
  279.     LLScrollPrompt AuthorList(title,3,0,80,15,20);
  280.     LineList* llist = (LineList*) 0;
  281.     LineList** ptr = &llist;
  282.     LineList* prev = (LineList*) 0;
  283.     int refnum = 0;
  284.     int i;
  285.     if (Tree->SearchAuthor(searchkey,&item)) {
  286.         do {
  287.             refnum++;
  288.             sprintf(line,"%3d: %s",refnum,item.key);
  289.             LineList* newline = new LineList(line,0,prev);
  290.             *ptr = newline;
  291.             prev = newline;
  292.             ptr = &newline->nextline;
  293.         } while (Tree->SearchAuthorAgain(&item));
  294.         if (llist != (LineList*) 0) {
  295.             if (refnum == 1) {
  296.                 if (Tree->SearchAuthor(llist->thisline+5,&item)) {
  297.                     sprintf(header,"Ids for author %s",item.key);
  298.                     ListRecord rec(&item.data);
  299.                     if (rec.ElementCount() == 1) DispCard(rec[0]);
  300.                     else if (rec.ElementCount() > 1)
  301.                         ListCardsFromList(header,rec);
  302.                 }
  303.             } else if (AuthorList.Scroll(llist,"Ref#, RETURN for more, q to exit:",title,KeySize) > 0) {
  304.                 refnum = atoi(title);
  305.                 for (i = 1,prev = llist;
  306.                      prev != (LineList*)0 && i < refnum;
  307.                      prev = prev->nextline,i++) ;
  308.                 if (i == refnum) {
  309.                     if (Tree->SearchAuthor(prev->thisline+5,&item)) {
  310.                         sprintf(header,"Ids for author %s",item.key);
  311.                         ListRecord rec(&item.data);
  312.                         if (rec.ElementCount() == 1) DispCard(rec[0]);
  313.                         else if (rec.ElementCount() > 1)
  314.                             ListCardsFromList(header,rec);
  315.                     }
  316.                 } else Term->Message("Bad reference number");
  317.             }
  318.             FreeLineList(llist);
  319.         }
  320.         return(-1);
  321.     } else {
  322.         Term->Message("No authors found");
  323.         return(1);
  324.     }
  325. }
  326.  
  327. int ListSubjects()
  328. {
  329.     CoreItem item;
  330.     Key searchkey;
  331.     static char title[80],header[80],line[LineLength];
  332.     Term->PromptLine(18,0,"Search prefix: ",searchkey,KeySize);
  333.     sprintf(title,"Subjects matching %s",searchkey);
  334.     LLScrollPrompt SubjectList(title,3,0,80,15,20);
  335.     LineList* llist = (LineList*) 0;
  336.     LineList** ptr = &llist;
  337.     LineList* prev = (LineList*) 0;
  338.     int refnum = 0;
  339.     int i;
  340.     if (Tree->SearchSubj(searchkey,&item)) {
  341.         do {
  342.             refnum++;
  343.             sprintf(line,"%3d: %s",refnum,item.key);
  344.             LineList* newline = new LineList(line,0,prev);
  345.             *ptr = newline;
  346.             prev = newline;
  347.             ptr = &newline->nextline;
  348.         } while (Tree->SearchSubjAgain(&item));
  349.         if (llist != (LineList*) 0) {
  350.             if (refnum == 1) {
  351.                 if (Tree->SearchSubj(llist->thisline+5,&item)) {
  352.                     sprintf(header,"Ids for subject %s",item.key);
  353.                     ListRecord rec(&item.data);
  354.                     if (rec.ElementCount() == 1) DispCard(rec[0]);
  355.                     else if (rec.ElementCount() > 1)
  356.                         ListCardsFromList(header,rec);
  357.                 }
  358.             } else if (SubjectList.Scroll(llist,"Ref#, RETURN for more, q to exit:",title,KeySize) > 0) {
  359.                 refnum = atoi(title);
  360.                 for (i = 1,prev = llist;
  361.                      prev != (LineList*)0 && i < refnum;
  362.                      prev = prev->nextline,i++) ;
  363.                 if (i == refnum) {
  364.                     if (Tree->SearchSubj(prev->thisline+5,&item)) {
  365.                         sprintf(header,"Ids for subject %s",item.key);
  366.                         ListRecord rec(&item.data);
  367.                         if (rec.ElementCount() == 1) DispCard(rec[0]);
  368.                         else if (rec.ElementCount() > 1)
  369.                             ListCardsFromList(header,rec);
  370.                     }
  371.                 } else Term->Message("Bad reference number");
  372.             }
  373.             FreeLineList(llist);
  374.         }
  375.         return(-1);
  376.     } else {
  377.         Term->Message("No subjects found");
  378.         return(1);
  379.     }
  380. }
  381.  
  382. static int Quit()
  383. {
  384.     return 0;
  385. }
  386.  
  387. static CommandDescr Main[] = {
  388.     { "Quit", Quit, 0 },
  389.     { "List Cards", ListCards, 0 },
  390.     { "List Titles", ListTitles, 0 },
  391.     { "List Authors", ListAuthors, 0 },
  392.     { "List Subjects", ListSubjects, 0 },
  393. };
  394.  
  395. const NumCommands = sizeof(Main) / sizeof(CommandDescr);
  396.  
  397. main(int argc,char** argv)
  398. {
  399.     static Librarian args(argc,argv);
  400.     vBTree tree(args.infile,ReadOnly,0);
  401.     if (tree.OpenStat() == failure) {
  402.         int error = errno;
  403.         cerr << "Could not open " << args.infile << ": "
  404.              << strerror(error) << "\n";
  405.         exit(error);
  406.     }
  407.     Terminal term;
  408.     Term = &term;
  409.     static CommandScreen mainScreen("Main Command Menu",NumCommands,Main);
  410.     Tree = &tree;
  411.  
  412.     mainScreen.RunScreen();
  413. }
  414.  
  415.  
  416.